<?php

namespace App\Services\Third;

use App\Constant\Enum;
use App\Libraries\Payment\DirectKylin\DirectKylinPayment;
use App\Libraries\Payment\WechatPay\WechatPayPayment;
use App\Models\Transaction;
use App\Models\UserWithdraw;
use Illuminate\Support\Facades\DB;

class TransactionService
{
    public static function transaction(UserWithdraw $userWithdraw): Transaction
    {
        DB::beginTransaction();
        try {
            $remark = sprintf("金币提现%s元", $userWithdraw->money);
            $transactionNo = Transaction::generateSerialNumber();
            $transferMethod = 'wechat';
            // 只会进行单比转账行为
            $detailNo = Transaction::generateDetailSerialNumber();
            list($callbackUrl, $payment) = self::getPayMethod($transferMethod);
            $params = [
                'transactionNo' => $transactionNo,
                'batchDetailNo' => $detailNo,
                'transAmount' => $userWithdraw->getAttribute('money'),
                'accountType' => 'WX_ACCOUNT', // @notice:: fixed
                'accountNo' => $userWithdraw->user->getAttribute('openid'),
                'outBizNo' => $transactionNo,
                'notifyUrl' => $callbackUrl,
                // SC01# 备注需要固定开头
                'remark' => $remark,
            ];
            $res = $payment::makeRequest($params);
            /** @var Transaction $transaction */

            $istransaction = Transaction::where('user_withdraw_id', $userWithdraw->getAttribute('id'))->first();
//避免重发创建记录
            //避免重发创建记录
            if (!empty($istransaction)) {
                throw new \Exception('请勿重复审核');
            } else {
                $transaction = Transaction::query()->create([
                    'user_id' => $userWithdraw->getAttribute('user_id'),
                    'user_withdraw_id' => $userWithdraw->getAttribute('id'),
                    'transaction_no' => $transactionNo,
                    'batch_detail_no' => $detailNo,
                    'trans_amount' => $params['transAmount'],
                    'account_type' => $params['accountType'],
                    'account_no' => $params['accountNo'],
                    'remote_order_no' => $res['orderId'],
                    'package_info' => $res['package_info'],
                    'bankinfo' => '',
                    'status' => Enum::TRANSACTION_STATUS_PENDING,
                ]);
            }
            if (!$transaction) {
                throw new \Exception('转账发起失败');
            }
            DB::commit();

            return $transaction;
        } catch (\Exception $exception) {
            DB::rollBack();
            throw $exception;
        }
    }

    protected static function getPayMethod(string $transferMethod): array
    {
        $host = config('services.host');
        switch ($transferMethod) {
            case 'wechat':
                $callbackUrl = sprintf('%s/payment/wechat/transfer-callback', $host);
                $payment = WechatPayPayment::class;
                break;
            default:
            case 'direct-kylin':
                $callbackUrl = sprintf('%s/payment/kylin/direct-transfer', $host);
                $payment = DirectKylinPayment::class;
        }

        return [$callbackUrl, $payment];
    }
}
